#pragma once
#include <functional>
#include <memory>

#include "Socket.hpp"
#include "Log.hpp"
#include "InetAddr.hpp"
#include "Protcol.hpp"

using func_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;
class IOService
{
public:
    IOService(func_t task)
        : _task(task)
    {
    }
    void IOExcute(SockPtr sock, InetAddr &client)
    {
        std::string packagestreamqueue;
        while (true)
        {
            // 1.读取网络字节流
            ssize_t n = sock->Recv(&packagestreamqueue);
            if (n <= 0)
            {
                LOG(INFO, "client %s quit or recv error\n", client.AddrString().c_str());
                break;
            }

            std::cout << "--------------------------------------------" << std::endl;
            std::cout << "packagestreamqueue: \n"
                      << packagestreamqueue << std::endl;

            // 我们能保证我们读到的是一个完整的报文吗？不能！

            // 2.拆封报文
            std::string package;
            package = Decode(packagestreamqueue);
            if (package.empty())
            {
                continue;
            }
            // 我们能保证我们读到的是一个完整的报文吗？能！
            std::cout << "package: \n"
                      << package << std::endl;

            // 3.反序列化
            auto req = Factory::BuildRequestDefault();
            req->Deserialize(package);
            req->Print();

            // 4.业务处理
            auto resp = _task(req);

            // 5.序列化
            std::string respjson;
            resp->Serialize(&respjson);
            std::cout << "respjson: \n"
                      << respjson << std::endl;
            // 6.拼接报文
            respjson = Encode(respjson);

            // 7.发送网络字节流
            sock->Send(respjson);
        }
    }

private:
    func_t _task; // 业务处理处理输入请求，返回响应
};